package lt.ntec.danblog.server.core.model.gae;

import java.util.List;

import javax.jdo.JDOException;
import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import lt.ntec.danblog.server.core.model.BaseDAO;
import lt.ntec.danblog.server.core.model.DAOException;
import lt.ntec.danblog.server.core.model.Persistable;

public abstract class JDOBaseDAO<T extends Persistable> implements BaseDAO<T> {

    final protected PersistenceManager pm;

    public JDOBaseDAO(PersistenceManager pm) {
        this.pm = pm;
    }

    @Override
    public T getById(Long id) {
        T post = null;
        try {
            post = pm.getObjectById(getEntityClass(), id);
        } catch (JDOObjectNotFoundException e) {
            return null;
        } catch (Exception e) {
            throw new DAOException(e);
        }
        return post;
    }

    @Override
    public void delete(T entity) {
        try {
            pm.currentTransaction().begin();
            pm.deletePersistent(entity);
            pm.currentTransaction().commit();
        } catch (Exception e) {
            throw new DAOException(e);
        }
    }

    @Override
    public Long save(T entity) {
        try {
            pm.currentTransaction().begin();
            pm.makePersistent(entity);
            pm.currentTransaction().commit();
        } catch (JDOException e) {
            throw new DAOException(e);
        }
        return entity.getId();
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> getList() {
        Query query = pm.newQuery(getEntityClass());
        List<T> list;
        try {
            list = (List<T>) (query.execute());
        } catch (Exception e) {
            throw new DAOException(e);
        }
        return list;
    }

    @Override
    public void delete(Long id) {
        T entity = getById(id);
        delete(entity);
    }

    public abstract Class<? extends T> getEntityClass();
}
